package com.example.template.controller;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import java.io.File;
import java.util.ArrayList;
import java.util.Objects;
import java.util.UUID;

/**
 * @author BuerYouth
 */
@Slf4j
@Controller
public class FileController {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 上传接口
     */
    @GetMapping("/upload")
    public ModelAndView upload(ModelAndView mv, @RequestParam("token") String token) {
        log.info("上传接收到token->" + token + ",id->" + stringRedisTemplate.opsForValue().get(token));
        mv.setViewName("upload");
        mv.addObject("token", token);
        return mv;
    }

    /**
     * 下载接口
     */
    @GetMapping("/download")
    public ModelAndView toDownload(ModelAndView mv, @RequestParam("token") String token) {
        log.info("下载接收到token->" + token + ",id->" + stringRedisTemplate.opsForValue().get(token));
        // 指定上传文件本地存储目录，不存在需要提前创建
        String dirPath = "E:/Temp/file/";
        ArrayList<String> files = new ArrayList<String>();
        File file = new File(dirPath);
        File[] fileList = file.listFiles();
        for (int i = 0; i < Objects.requireNonNull(fileList).length; i++) {
            // 获取文件
            if (fileList[i].isFile()) {
                log.info("文 件：" + fileList[i].getName());
                files.add(fileList[i].getName());
            }
            // 获取目录
            if (fileList[i].isDirectory()) {
                log.info("文件夹：" + fileList[i]);
            }
        }
        mv.setViewName("download");
        mv.addObject("files", files);
        mv.addObject("token", token);
        return mv;
    }

    /**
     * 上传单个文件
     */
    @PostMapping("/uploadFile")
    public String uploadFile(@RequestParam("file") MultipartFile fileUpload, Model mv) {
        String fileName = fileUpload.getOriginalFilename();
        log.info("接收到文件上传->" + fileName);
        // 重新生成文件名（根据具体情况生成对应文件名）
        fileName = UUID.randomUUID() + "_" + fileName;
        // 指定上传文件本地存储目录，不存在需要提前创建
        String dirPath = "E:/Temp/file/";
        File filePath = new File(dirPath);
        // 判断是否有该目录
        if (!filePath.exists()) {
            filePath.mkdirs();
        }
        try {
            fileUpload.transferTo(new File(dirPath + fileName));
            mv.addAttribute("uploadStatus", "上传成功！");
        } catch (Exception e) {
            e.printStackTrace();
            // 上传失败，返回失败信息
            mv.addAttribute("uploadStatus", "上传失败" + e.getMessage());
        }
        return "upload";
    }

    /**
     * 下载文件
     */
    @GetMapping("/downloadFile")
    public ResponseEntity<byte[]> fileDownload(@RequestParam("filename") String filename) {
        log.info("请求下载->" + filename);
        // 指定下载文件本地存储目录
        String dirPath = "E:/Temp/file/";
        File file = new File(dirPath + File.separator + filename);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentDispositionFormData("attachment", filename);
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        try {
            return new ResponseEntity<>(FileUtils.readFileToByteArray(file), headers, HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity<byte[]>(e.getMessage().getBytes(), HttpStatus.EXPECTATION_FAILED);
        }
    }

}
